package gov.pbc.nn.kjgl.maintenance.view;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.orm.ParseResult;
import com.bstek.bdf2.core.orm.hibernate.ISessionCallback;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.model.ProcessInstance;
import com.bstek.uflo.model.ProcessInstanceState;
import com.bstek.uflo.service.StartProcessInfo;

import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.dao.CommonHibernateDao;
import gov.pbc.nn.core.dao.CommonJdbcDao;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.utils.EntityRowMapperUtils;
import gov.pbc.nn.core.utils.MapUtils;
import gov.pbc.nn.core.utils.SecurityUtils;
import gov.pbc.nn.kjgl.maintenance.entity.SysEntity;
import gov.pbc.nn.kjgl.maintenance.entity.SysEvent;
import gov.pbc.nn.kjgl.maintenance.entity.SysProblem;
import gov.pbc.nn.uflo.UfloUtils;
import gov.pbc.nn.uflo.entity.Opinion;

@Component
public class SysProblemPR {

	@Resource(name = CommonHibernateDao.BEAN_ID)
	private CommonHibernateDao hibernateDao;
	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao coreHibernateDao;
	@Resource(name = CommonJdbcDao.BEAN_ID)
	private CommonJdbcDao jdbcDao;
	@Resource(name = ProcessClient.BEAN_ID)
	private ProcessClient pc;
	@Resource(name = TaskClient.BEAN_ID)
	private TaskClient tc;

	public static final String PROCESS_NAME = "系统问题管理";

	@DataProvider
	public void loadProblem(Page<SysProblem> page, Criteria criteria) {
		String sql = "";
		Map<String, Object> map = new HashMap<String, Object>();
		Dept dept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
		Dept zzDept = (Dept) SecurityUtils.getZZByDept(dept);
		if (Dept.NANNING.equals(zzDept.getId())) {
			sql = "select a.*,b.FILE_NAME_ from t_sys_problem as a left join t_sys_material as b on a.SCHEME_ID_ =b.ID_ where a.INVALID_=0 ORDER BY a.CREATE_DATE_";
			map = new HashMap<String, Object>();
			ParseResult pr = jdbcDao.parseCriteria(criteria, true, null);
			if (pr != null) {
				StringBuffer sbSql = pr.getAssemblySql();
				sql += " and " + sbSql;
				map.putAll(pr.getValueMap());
			}
		}
		else {
			sql="select a.*,b.FILE_NAME_ from t_sys_problem as a left join t_sys_material as b on a.SCHEME_ID_ =b.ID_ "
		       +" where a.INVALID_=0 and a.sys_id_ in (select s.id_ from T_SYS_ENTITY as s where s.INVALID_=0 and (s.DEPT_ID_ =:deptId or s.OPERATION_DEPT_ID_=:deptId)) "
			   +" order by a.CREATE_DATE_";
			ParseResult pr = jdbcDao.parseCriteria(criteria, true, "a");
			map.put("deptId", dept.getId());
			if (pr != null) {
				StringBuffer sbSql = pr.getAssemblySql();
				sql += " and " + sbSql;
				map.putAll(pr.getValueMap());
			}
		}
		this.jdbcDao.pagingQuery(page, sql, new RowMapper<SysProblem>() {
			@Override
			public SysProblem mapRow(ResultSet rs, int rowNum) throws SQLException {
				// TODO Auto-generated method stub
				SysProblem sp = EntityRowMapperUtils.get(SysProblem.class, rs, rowNum);
				try {
					sp = EntityUtils.toEntity(sp);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				EntityUtils.setValue(sp, "schemeName", rs.getString("FILE_NAME_"));
				return sp;

			}
		}, map);

		// DetachedCriteria dc =
		// this.hibernateDao.buildDetachedCriteria(criteria,
		// SysProblem.class);
		// dc.add(Restrictions.eq("invalid", false));
		// this.hibernateDao.pagingQuery(page, dc);
	}

	@DataProvider
	public List<SysEntity> getSysEntities(String filter) {
		DetachedCriteria dc = DetachedCriteria.forClass(SysEntity.class);
		dc.add(Restrictions.eq("invalid", false));
		dc.add(Restrictions.eq("auditState", 2));
		Dept dept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
		Dept zzDept = (Dept) SecurityUtils.getZZByDept(dept);
		if (!Dept.NANNING.equals(zzDept.getId())) {
		dc.add(Restrictions.or(Restrictions.eq("deptId", dept.getId()), Restrictions.eq("operationDeptId", dept.getId())));
		}
		if (StringUtils.isNotBlank(filter)) {
			dc.add(Restrictions.like("name", "%"+filter+"%"));
		}
		return (List<SysEntity>) this.hibernateDao.query(dc);
	}

	@DataResolver
	@Transactional
	public void saveProblem(SysProblem problem) {
		EntityState state = EntityUtils.getState(problem);
		if (state == EntityState.NEW) {
			this.hibernateDao.save(problem);
		} else {
			if (state == EntityState.MODIFIED) {
				this.hibernateDao.update(problem);
			}
		}
	}

	@Expose
	@Transactional
	public void deleteProblem(final String id) {
		String result = this.canDelete(id);
		if(result!=null){
			throw new UnsupportedOperationException("result");
		}
		this.hibernateDao.delete(id, SysProblem.class);
		UfloUtils.deleteProcessInstance(id,true);
	}

	@Expose
	public String canDelete(String id) {
		if (UfloUtils.hasHistoryProcessInstance(id)) {
			return "当前任务已经审批完成，不能删除！";
		}
		return null;
	}

	@Expose
	public String canModify(String id) {
		if (UfloUtils.isInProcessInstance(id)) {
			return "当前任务正在审批过程中，不能修改！";
		}
		if (UfloUtils.hasHistoryProcessInstance(id)) {
			return "当前任务已经审批完成，不能修改！";
		}
		return null;
	}

	/**
	 * 开启流程
	 * 
	 * @param problemId
	 * @throws Exception
	 */
	@Transactional
	@DataResolver
	public void startProcess(SysProblem problem) throws Exception {
		problem.setState(5);
		EntityState state = EntityUtils.getState(problem);
		if(state!=EntityState.NEW){
			EntityUtils.setState(problem, EntityState.MODIFIED);
		}
		this.saveProblem(problem);
		if (UfloUtils.isInProcessInstance(problem.getId())) {
			throw new UnsupportedOperationException("当前任务正在审批过程中，不能重复发起申请！");
		}
		if (UfloUtils.hasHistoryProcessInstance(problem.getId())) {
			throw new UnsupportedOperationException("当前任务已经审批完成，不能重复发起申请！");
		}
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("sysId", problem.getSysId());
		variables.put("taskname", "【" + problem.getSysName() + "】系统问题,需运维人员处理");
		StartProcessInfo spi = new StartProcessInfo();
		spi.setBusinessId(problem.getId());
		spi.setCompleteStartTask(true);
		spi.setPromoter(ContextHolder.getLoginUserName());
		spi.setVariables(variables);
		this.pc.startProcessByName(PROCESS_NAME, spi);
	}
}
